package com.zhuss.food.product;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.zhuss.bean.bo.food.food.DetailFoodBo;
import com.zhuss.bean.bo.food.product.DetailProductBo;
import com.zhuss.bean.bo.food.product.SearchProductBo;
import com.zhuss.bean.bo.food.product.box.wechat.ListBoxBo;
import com.zhuss.bean.bo.food.product.stirfry.wechat.ListStirfryBo;
import com.zhuss.bean.bo.food.product.stirfry.wechat.ListStirfryFetchTimeBo;
import com.zhuss.bean.bo.food.product.takeout.wechat.ListTakeoutBo;
import com.zhuss.bean.bo.food.product.takeout.wechat.ListTakeoutStartTimeBo;
import com.zhuss.bean.bo.food.product.week.wechat.ListFloorBo;
import com.zhuss.bean.bo.food.product.week.wechat.ListFloorMenuBo;
import com.zhuss.bean.bo.food.product.week.wechat.ListWeekDayBo;
import com.zhuss.bean.bo.food.product.week.wechat.ListWeekMenuBo;
import com.zhuss.bean.unit.food.MenuFoodTime;
import com.zhuss.bean.unit.food.ProductSimple;
import com.zhuss.bean.unit.food.Stirfry;
import com.zhuss.bean.unit.food.StirfryFetchTime;
import com.zhuss.bean.unit.food.StirfryProduct;
import com.zhuss.bean.unit.food.Takeout;
import com.zhuss.bean.vo.food.food.DetailFoodVo;
import com.zhuss.bean.vo.food.product.DetailProductVo;
import com.zhuss.bean.vo.food.product.ListProductVo;
import com.zhuss.bean.vo.food.product.box.wechat.BoxProductVo;
import com.zhuss.bean.vo.food.product.takeout.wechat.StartListVo;
import com.zhuss.bean.vo.food.product.takeout.wechat.TakeoutProductVo;
import com.zhuss.bean.vo.food.product.week.wechat.FloorFoodVo;
import com.zhuss.bean.vo.food.product.week.wechat.FloorVo;
import com.zhuss.bean.vo.food.product.week.wechat.WeekDayListVo;
import com.zhuss.common.PageVo;
import com.zhuss.common.Period;
import com.zhuss.common.ReadService;
import com.zhuss.common.SelectVo;
import com.zhuss.core.processor.EnumConfig;
import com.zhuss.core.processor.ScheduleRead;
import com.zhuss.enums.ConfigTypeEnum;
import com.zhuss.enums.EnumUtil;
import com.zhuss.enums.ProductType;
import com.zhuss.enums.UpperDownEnum;
import com.zhuss.exception.WpsException;
import com.zhuss.food.db.entity.Product;
import com.zhuss.food.processor.FoodRead;
import com.zhuss.food.processor.OrderRead;
import com.zhuss.food.processor.ProductRead;
import com.zhuss.util.DateUtil;
import com.zhuss.util.FloorUtil;


/**
 * 商品查询service（基本查询）
 * @author zhushanshuo
 * @Date 2020/03/01 16:01
 *
 */
@Component("productReadService")
public class ProductReadService implements ReadService<Object, Object> {
	
	@Autowired
	@Qualifier("productRead")
	private ProductRead productRead;
	
	@Autowired
	@Qualifier("foodRead")
	private FoodRead foodRead;
	
	@Autowired
	@Qualifier("orderRead")
	private OrderRead orderRead;
	
	@Autowired
	@Qualifier("scheduleRead")
	private ScheduleRead scheduleRead;
	
	@Autowired
	@Qualifier("enumConfig")
	private EnumConfig enumConfig;
	
	@Autowired
	@Qualifier("foodReadService")
	private ReadService<Object, Object> foodReadService;
	
	/**
	 * 详情
	 */
	@Override
	public Object detail(Object param) throws WpsException {
		DetailProductBo bo = (DetailProductBo) param;
		Long productId = bo.getProductId();
		DetailProductVo vo = (DetailProductVo) productRead.detail(productId);
		vo.setFoodName(((DetailFoodVo) foodRead.detail(vo.getFoodId())).getName());
		vo.setCategoryName(enumConfig.categoryName(vo.getCategory(), vo.getArea()));
		return vo;
	}
	
	/**
	 * 列表
	 * @throws WpsException 
	 */
	@Override
	@SuppressWarnings("unchecked")
	public Object list(Object param) throws WpsException {
		SearchProductBo bo = (SearchProductBo) param;
		Object result = productRead.list(bo);
		List<ListProductVo> list = ((PageVo<ListProductVo>) result).getItems();
		for (ListProductVo item : list) {
			String foodName = ((DetailFoodVo) foodRead.detail(item.getFoodId())).getName();
			String categoryName = enumConfig.categoryName(item.getCategory(), item.getArea());
			item.setFoodName(foodName);
			item.setCategoryName(categoryName);
		}
		return result;
	}

	public Object listStirfryFetchTime(Object param) {
		ListStirfryFetchTimeBo bo = (ListStirfryFetchTimeBo) param;
		List<StirfryFetchTime> result = new ArrayList<StirfryFetchTime>();
    	result = scheduleRead.listStirfryFetchTime(bo);
    	return result;
	}
	
	
	public Object listFloor(Object param) throws WpsException {
		ListFloorBo bo = (ListFloorBo) param;
		List<FloorVo> result = new ArrayList<>();
		
		result = FloorUtil.floorList(bo.getConcurrentArea());
		
		
		return result;
	}
	
	public Object listFloorMenu(Object param) throws WpsException {
		ListFloorMenuBo bo = (ListFloorMenuBo) param;
		List<FloorFoodVo> result = new ArrayList<FloorFoodVo>();
		Date date = DateUtil.toDateOnly(new Date());
		Integer productTime = bo.getFoodTimeId();
		Integer floor = bo.getFloorId();
		FloorFoodVo v = new FloorFoodVo();
		v.setHaveTime((Period) EnumUtil.containsKeyReturnData(com.zhuss.enums.FoodTime.class, productTime.intValue()));
		v.setFoodTimeId(productTime.longValue());
		Integer area = bo.getConcurrentArea();
		List<Product> productList = productRead.listMenu(UpperDownEnum.上架.key(), date, productTime, floor, area, ProductType.一周菜单.key());
		List<ProductSimple> productSimpleList = new ArrayList<ProductSimple>();
		for (Product p : productList) {
			Long foodId = p.getFoodId();
			DetailFoodBo foodBo = new DetailFoodBo();
			foodBo.setFoodId(foodId);
			DetailFoodVo food = (DetailFoodVo) foodReadService.detail(foodBo);
			ProductSimple productSimple = new ProductSimple();
			productSimple.setProductId(p.getProductId());
			productSimple.setProductName(p.getName());
			String pic = food.getPicUrl();
			productSimple.setPicUrl(pic);
			productSimpleList.add(productSimple);
		}
		
		v.setProductList(productSimpleList);
		int groupNum = 0;
		int everyGroup = 4;
		int size = productSimpleList.size();
		groupNum = size % everyGroup == 0 ? size / everyGroup : size / everyGroup + 1;
		List<List<ProductSimple>> groupList = new ArrayList<>(groupNum);
		List<ProductSimple> group = new ArrayList<ProductSimple>();
		for (int i = 0; i <= size - 1; i ++) {
			if (group.size() < everyGroup) {
				group.add(productSimpleList.get(i));
				if (group.size() == everyGroup || i == size - 1) {
					groupList.add(group);
				}
			} else {
				group = new ArrayList<ProductSimple>();
				group.add(productSimpleList.get(i));
				if (i == size - 1) {
					groupList.add(group);
				}
			}
		}
		v.setProductGroupList(groupList);
		result.add(v);
		return result;
	}
	
	
	public Object listWeekDay(Object param) throws WpsException {
		ListWeekDayBo bo = (ListWeekDayBo) param;
		WeekDayListVo result = new WeekDayListVo();
		
		result.setWeekDayList(DateUtil.toWeek(bo.getConcurrentArea()));
		
		return result;
	}
	
	public Object listWeekMenu(Object param) throws WpsException {
		ListWeekMenuBo bo = (ListWeekMenuBo) param;
		List<MenuFoodTime> result = new ArrayList<MenuFoodTime>();
		Date date = DateUtil.toDateOnly(bo.getDate());
		Integer area = bo.getConcurrentArea();
		List<Product> productList = productRead.listWeekMenu(date, area);
		
		List<SelectVo> selectVoList = EnumUtil.listSelect(com.zhuss.enums.FoodTime.class);
		for (SelectVo sv : selectVoList) {
			MenuFoodTime mft = new MenuFoodTime();
			mft.setFoodTime(sv.getId());
			mft.setFoodTimeName(sv.getName());
			List<ProductSimple> productSimpleList = new ArrayList<ProductSimple>();
			for (Product p : productList) {
				if (mft.getFoodTime().equals(p.getProductTime())) {
					ProductSimple productSimple = new ProductSimple();
					productSimple.setProductId(p.getProductId());
					productSimple.setProductName(p.getName());
					productSimpleList.add(productSimple);
				}
			}
			mft.setProductList(productSimpleList);
			result.add(mft);
		}
		
		return result;
	}
	
	public Object listTakeoutStartTime(Object param) throws WpsException {
		ListTakeoutStartTimeBo bo = (ListTakeoutStartTimeBo) param;
		Integer area = bo.getConcurrentArea();
    	List<Long> startList = new ArrayList<Long>();
    	List<SelectVo> selectVoList = enumConfig.listSelectTakeoutStartTime(area);
    	for (SelectVo sv : selectVoList) {
    		String time = sv.getName();
    		long startTime = DateUtil.toDateLongByTimeMinute(time);
    		startList.add(startTime);
    	}
    	StartListVo result = new StartListVo();
    	result.setStartList(startList);
    	result.setNow(DateUtil.calculateStart(selectVoList, false));
    	result.setEnd(enumConfig.getTime(ConfigTypeEnum.外卖截止时间.tag(), area).getTime());
    	return result;
	}
	
	
	public Object listTakeout(Object param) throws WpsException {
		ListTakeoutBo bo = (ListTakeoutBo) param;
		TakeoutProductVo result = new TakeoutProductVo();
		Date startTime = bo.getStart();
		Date date = DateUtil.toDateOnly(new Date());
		Integer area = bo.getConcurrentArea();
		Long userId = bo.getConcurrentUserId();
		List<Product> productList = productRead.listTakeout(startTime, date, area);
		List<Takeout> takeoutList = transferToTakeout(productList, userId);
		Long nextStart = DateUtil.calculateStart(enumConfig.listSelectTakeoutStartTime(area), true);
		result.setNextStart(nextStart);
		result.setTakeoutList(takeoutList);
		return result;
	}
	
	private List<Takeout> transferToTakeout(List<Product> productList, Long userId) throws WpsException {
		List<Takeout> takeoutList = new ArrayList<Takeout>();
		for (Product p : productList) {
			Integer alreadyBuyNum = orderRead.alreadyBuyNum(userId, p.getProductId());
			Long foodId = p.getFoodId();
			DetailFoodBo foodBo = new DetailFoodBo();
			foodBo.setFoodId(foodId);
			DetailFoodVo food = (DetailFoodVo) foodReadService.detail(foodBo);
			Takeout s = new Takeout();
			s.setAlreadyBuyNum(alreadyBuyNum);
			s.setEnd(p.getEndTime().getTime());
			s.setStart(p.getStartTime().getTime());
			s.setName(p.getName());
			s.setPicUrl(food.getPicUrl());
			s.setPrice(food.getPrice());
			s.setProductId(p.getProductId());
			s.setProductNo(p.getProductNo());
			s.setRealPrice(p.getPrice());
			s.setTotal(p.getTotal());
			s.setUsed(p.getUsed());
			takeoutList.add(s);
		}
		return takeoutList;
	}
	
	public Object listBox(Object param) throws WpsException {
		ListBoxBo bo = (ListBoxBo) param;
		BoxProductVo result = new BoxProductVo();
		Integer area = bo.getConcurrentArea();
		Date date = DateUtil.toDateOnly(new Date());
		List<Product> productList = productRead.listBox(date, area);
		if(productList != null && productList.size() > 0){
			Product product = productList.get(0);
			result.setName(product.getName());
			result.setProductId(product.getProductId());
			result.setProductNo(product.getProductNo());
		}
		return result;
	}
	
	public Object listDinner(Object param) throws WpsException {
		
		return listStirfry(param);
	}
	
	public Object listStirfry(Object param) throws WpsException {
		ListStirfryBo bo = (ListStirfryBo) param;
		List<StirfryProduct> result = new ArrayList<StirfryProduct>();
		
		Integer area = bo.getConcurrentArea();
		
		Date end = enumConfig.getTime(ConfigTypeEnum.点炒截止点餐时间.tag(), area);
		
		List<SelectVo> selectList = enumConfig.listSelectFoodCategory(area);
		for (SelectVo vo : selectList) {
			Date date = DateUtil.toDateOnly(new Date());
			List<Product> productList = productRead.listStirfry(vo.getId(), date, area);
			StirfryProduct item = new StirfryProduct();
			item.setCategory(vo.getId());
			item.setCategoryTag(vo.getTag());
			item.setCategoryName(vo.getName());
			item.setStirfryList(transferToStirfry(productList, item.getCategory()));
			if (!item.getStirfryList().isEmpty()) {
				result.add(item);
			}
			item.setEnd(end.getTime());
			
		}
		return result;
	}
	
	private List<Stirfry> transferToStirfry(List<Product> productList, Integer category) throws WpsException {
		List<Stirfry> list = new ArrayList<Stirfry>();
		for (Product p : productList) {
			Long foodId = p.getFoodId();
			DetailFoodBo foodBo = new DetailFoodBo();
			foodBo.setFoodId(foodId);
			DetailFoodVo food = (DetailFoodVo) foodReadService.detail(foodBo);
			Stirfry s = new Stirfry();
			s.setName(p.getName());
			s.setPrice(p.getPrice());
			s.setProductId(p.getProductId());
			s.setProductNo(p.getProductNo());
			s.setPicUrl(food.getPicUrl());
			s.setCount(0l);
			s.setCategory(category);
			list.add(s);
		}
    	return list;
	}
	
	
	
}

